{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 反卷积： 转置卷积\n",
    "一些卷积操作的动图\n",
    "https://github.com/vdumoulin/conv_arithmetic\n",
    "\n",
    "\n",
    "作者：谭旭\n",
    "链接：https://www.zhihu.com/question/43609045/answer/132235276\n",
    "来源：知乎\n",
    "著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。\n",
    "\n",
    "Deconvolution大致可以分为以下几个方面：（1）unsupervised learning，其实就是covolutional sparse coding[1][2]：这里的deconv只是观念上和传统的conv反向，传统的conv是从图片生成feature map，而deconv是用unsupervised的方法找到一组kernel和feature map，让它们重建图片。（2）CNN可视化[3]：通过deconv将CNN中conv得到的feature map还原到像素空间，以观察特定的feature map对哪些pattern的图片敏感，这里的deconv其实不是conv的可逆运算，只是conv的transpose，所以tensorflow里一般取名叫transpose_conv。（3）upsampling[4][5]：在pixel-wise prediction比如image segmentation[4]以及image generation[5]中，由于需要做原始图片尺寸空间的预测，而卷积由于stride往往会降低图片size， 所以往往需要通过upsampling的方法来还原到原始图片尺寸，deconv就充当了一个upsampling的角色。\n",
    "\n",
    "先看一下卷积操作的实现：\n",
    "将输入矩阵展开，同时将卷积核扩展为图3\n",
    "![](imgs/conv(1).jpg)\n",
    "![](imgs/conv(2).jpg)\n",
    "![](imgs/conv(3).jpg)\n",
    "## 逆卷积(Deconvolution)比较容易引起误会，转置卷积(Transposed Convolution)是一个更为合适的叫法.\n",
    "\n",
    "举个栗子：\n",
    "\n",
    "4x4的输入，卷积Kernel为3x3, 没有Padding / Stride, 则输出为2x2。\n",
    "![](http://deeplearning.net/software/theano_versions/dev/_images/no_padding_no_strides.gif)\n",
    "\n",
    "根据上述的矩阵计算卷积的内容，可以把卷积核展开，写成矩阵运算的形式：$y = Cx$\n",
    "![](imgs/conv.jpg)\n",
    "\n",
    "而转置卷积就是\n",
    "$$\n",
    "y = C^Tx\n",
    "$$\n",
    "\n",
    "\n",
    "\n",
    "具体可以看这个动图：http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic\n",
    "### 卷积\n",
    "![](http://deeplearning.net/software/theano_versions/dev/_images/padding_strides.gif)\n",
    "\n",
    "### 没有padding stride 的deconv\n",
    "![](http://deeplearning.net/software/theano_versions/dev/_images/no_padding_no_strides_transposed.gif)\n",
    "\n",
    "### Here is an example for i = 5, k = 3 and s = 2:deconv\n",
    "![](http://deeplearning.net/software/theano_versions/dev/_images/no_padding_strides_transposed.gif)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
